/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.admin.client.components;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.elf.gwt.admin.client.AdminComponentController;
import com.elf.gwt.admin.client.utils.AdminUtils;
import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.model.AttributeModel;
import com.elf.gwt.common.client.model.AttributeValueModel;
import com.elf.gwt.common.client.model.DetailedProductModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 *  
 */
public class ProductSearchComponent extends EditTableComponent
{	
	protected static CategoriesProductsComponent categoriesProductsComponent = null;
	protected List<DetailedProductModel> productModels;
	protected DialogBox imageDialogBox = null;
	protected Image dialogImage = null;
	protected TextBox keywordsTextBox;
	protected DialogBox parentDialogBox = null;

	/**
	 * Constructor
	 */
	public ProductSearchComponent(AdminComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix);
		productModels = new ArrayList<DetailedProductModel>();
		paginate = true;
		tableType = "products";
		editable = false;
		if (categoriesProductsComponent == null) categoriesProductsComponent = (CategoriesProductsComponent)controller.getComponent("CategoriesProductsComponent");
	}
	
	public ProductSearchComponent(DialogBox parentDialogBox,  AdminComponentController controller, String stylePrefix)
	{
		this(controller, stylePrefix);
		this.parentDialogBox = parentDialogBox;
	}

	public void additionalRequestParameters()
	{
		addRequestParameter(new RequestParameter("action", action));
		addRequestParameter(new RequestParameter("paginate", paginate));
		if (paginate) {
			addRequestParameter(new RequestParameter("max_rows", maxRows));
			addRequestParameter(new RequestParameter("offset", offset));
		}

		Iterator<String> iterElements = elements.keySet().iterator();
		while (iterElements.hasNext())
		{
			String key = iterElements.next();
			Widget widget = elements.get(key);
			String value = CommonUtils.getValue(widget);
			if (value != null && value.length() > 0) addRequestParameter(new RequestParameter(key, value));
		} 
		edit = false;
		action = "";
	}

	protected void buildMetaModel(JSONObject jsonObject) throws Exception
	{
		super.buildMetaModel(jsonObject);
	}

	protected void buildModel(JSONArray jsonArray) throws Exception
	{
		productModels.clear();
		super.buildModel(jsonArray);
	}

	protected void buildModel(JSONObject jsonObject) throws Exception
	{
		DetailedProductModel model = new DetailedProductModel(jsonObject, 400, 400);
		productModels.add(model);
	}

	//Using on Built to slip in extra fields at top of component
	public void onBuilt()
	{
		if (numberOfTableEntries != 1) {
			Grid grid = new Grid(1,3);
			int numrow = 0;
			if (keywordsTextBox == null) keywordsTextBox = new TextBox(); 
			elements.put("keywords", keywordsTextBox);
			grid.setText(numrow, 0, "Keywords");
			grid.setWidget(numrow, 1, keywordsTextBox);
			keywordsTextBox.addKeyUpHandler(searchKeyboardHandler);
			Button searchButton = new Button("search", cancelHandler);
			searchButton.addStyleName("ComponentLink");
			grid.setWidget(numrow, 2, searchButton);
			numrow++;

			insert(grid, 0);
		}
		
		Widget widget = this.getParent();
		if (widget instanceof FlowPanel) {
			FlowPanel fp = (FlowPanel)widget;
			int cnt = fp.getWidgetCount();
			for (int i = 0; i < cnt; i++) {
				widget = fp.getWidget(i);
				if (widget instanceof HorizontalPanel)
				{
					if (widget.getTitle().equals("Button Panel")) {
						HorizontalPanel hp = (HorizontalPanel)widget;
						int cnt1 = hp.getWidgetCount();
						for (int j = 0; j < cnt1; j++) {
							widget = hp.getWidget(j);
							if (widget.getTitle().equals("add product")) {
								widget.setVisible(numberOfTableEntries == 1);
							}
						}
						
						break;
					}
				}
			}
			
		}
		widget = this.getParent().getParent().getParent();
		if (widget instanceof DialogBox) {
			DialogBox db = (DialogBox)widget;
			db.center();
		}

		super.onBuilt();
		
		if (parentDialogBox != null) {
			parentDialogBox.center();
			parentDialogBox.show();
		}
	}


	public void buildFromModel() throws Exception
	{
		numberOfTableEntries = productModels.size();
		if (numberOfTableEntries == 0) {
			clear();
			elements.clear();
			add(new Label("Sorry, but the keywords you have selected resulted in 0 products returned from search"));
			onBuilt();
		}
		else if (numberOfTableEntries == 1) {
			//Display a single value
			DetailedProductModel model = productModels.get(0);
			clear();
			Grid grid = new Grid(1,2);
			add(grid);
			VerticalPanel vpanel = new VerticalPanel();
			grid.setWidget(0, 0, vpanel);
			updateButton = new Button("back to search", clearHandler);
			updateButton.addStyleName("ComponentLink");
			vpanel.add(updateButton);

			Image image = new Image();
			image.setUrl(AdminUtils.getImageProductsDirectory() + model.getImage());
			String[] imageSize = model.getImageSize();
			image.setSize(imageSize[0], imageSize[1]);
			grid.setWidget(0, 1, image);
			
			vpanel.add(new Label(model.getName()));
			vpanel.add(new Label(model.getModel()));

			List<AttributeModel> attributes = model.getAttributes();
			
			int sz = attributes.size();
			if (sz > 0)
			{
				vpanel.add(new InlineLabel("Available Options:"));
				Grid optionsGrid = new Grid(sz, 2);
				vpanel.add(optionsGrid);
				for (int i = 0; i< sz; i++)
				{
					AttributeModel attribute = attributes.get(i);
					optionsGrid.setText(i, 0, attribute.getName());
					ListBox listBox = new ListBox();
					elements.put("attributes-" + i, listBox);
					optionsGrid.setWidget(i, 1, listBox);
					List<AttributeValueModel> values = attribute.getValues();
					int vsz = values.size();
					NumberFormat fmt = NumberFormat.getCurrencyFormat(AdminComponentController.currenciesAdministrationComponent.getCurrencyModel().getCode());
					for (int j= 0; j< vsz; j++)
					{
						AttributeValueModel value = values.get(j);
						String valueName = value.getName();
						if (value.getPrice() != 0)
						{
							double valuePrice = value.getPrice() * AdminComponentController.currenciesAdministrationComponent.getCurrencyModel().getValue();

							valueName = valueName +  " (" + value.getPrefix() + fmt.format(valuePrice) + ")";
						}
						String valueId = String.valueOf(value.getAttributeId()) + "_" + String.valueOf(value.getId());
						listBox.addItem(valueName, valueId);
						if (j == 0)
						{
							listBox.setSelectedIndex(j);
						}
					}
				}
			}
			onBuilt();
		}
		else {
			numberOfTableColumns = 4;
			super.buildFromModel();
		}
	}

	public void displayHeader(Grid grid) {
		grid.setText(0, 0, "Action");
		grid.setText(0, 1, "Model");
		grid.setText(0, 2, "Name");
		grid.setText(0, 3, "Image");
	}

	public void displayRow(Grid grid, int row, int entryIndex) {
		displayRow(grid, row, productModels.get(entryIndex));
	}

	public void displayRow(Grid grid, int row, DetailedProductModel model) {

		InlineLabel userLoginLabel = new InlineLabel("select");
		userLoginLabel.setStyleName("ComponentLink");
		userLoginLabel.addStyleName("index:"+(row-1));
		userLoginLabel.addClickHandler(selectClickHandler);

		InlineLabel editLabel = new InlineLabel("image");
		editLabel.setStyleName("ComponentLink");
		editLabel.addStyleName("index:"+(row-1));
		editLabel.addMouseOverHandler(mouseOverHandler);
		editLabel.addMouseOutHandler(mouseOutHandler);
		
		grid.setWidget(row, 0, userLoginLabel);
		grid.setText(row, 1, model.getModel());
		grid.setText(row, 2, model.getName());
		grid.setWidget(row, 3, editLabel);
	}

	protected ClickHandler selectClickHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			Widget source = (Widget)event.getSource();
			String stylenames = source.getStyleName();
			int loc = stylenames.indexOf("index:");
			stylenames = stylenames.substring(loc+6);
			loc = stylenames.indexOf(" ");
			if (loc > -1) stylenames = stylenames.substring(0, loc);
			int index = Integer.parseInt(stylenames);
			DetailedProductModel productModel = getProductModels().get(index);
			elements.put("productId", new InlineLabel("" + productModel.getId()));
			build(true);
		}
	};

	protected MouseOverHandler mouseOverHandler = new MouseOverHandler() {
		public void onMouseOver(MouseOverEvent event)
		{
			Widget source = (Widget)event.getSource();
			String stylenames = source.getStyleName();
			int loc = stylenames.indexOf("index:");
			stylenames = stylenames.substring(loc+6);
			loc = stylenames.indexOf(" ");
			if (loc > -1) stylenames = stylenames.substring(0, loc);
			int index = Integer.parseInt(stylenames);
			DetailedProductModel model = getProductModels().get(index);
			String imagename = model.getImage();
			if (imageDialogBox == null) {
				imageDialogBox = new DialogBox();
				imageDialogBox.setStyleName(getHandle() + "DialogBox");
				imageDialogBox.setModal(false);
				dialogImage = new Image();
				imageDialogBox.add(dialogImage);
			}
			dialogImage.setUrl(AdminUtils.getImageProductsDirectory() + imagename);
			String[] imageSize = model.getImageSize();
			int width = Integer.parseInt(imageSize[0]);
			int height = Integer.parseInt(imageSize[1]);
			dialogImage.setSize(String.valueOf(width), String.valueOf(height));
			imageDialogBox.center();
			imageDialogBox.show();
		}
	};

	protected MouseOutHandler mouseOutHandler = new MouseOutHandler() {
		public void onMouseOut(MouseOutEvent event)
		{
			if (imageDialogBox != null  && imageDialogBox.isShowing()) imageDialogBox.hide();
		}
	};

	public List<DetailedProductModel> getProductModels() {
		return productModels;
	}
	
	protected ClickHandler clearHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			elements.clear();
			build(true);
		}
	};
	
	protected KeyUpHandler searchKeyboardHandler = new KeyUpHandler() {
		public void onKeyUp(KeyUpEvent event) {
			if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
				action = "";
				build(true);
			}
		}
	};
}
